#ifndef USB_H
#define USB_H

#include <stdint.h>

/*--------- USB数据结构 ------------ */
typedef volatile struct {
    uint8_t bLength;
    uint8_t bDescriptorType;
    uint16_t bcdUSB;
    uint8_t bDeviceClass;
    uint8_t bDeviceSubClass;
    uint8_t bDeviceProtocol;
    uint8_t bMaxPacketSize0;
    uint16_t idVendor;
    uint16_t idProduct;
    uint16_t bcdDevice;
    uint8_t iManufacturer;
    uint8_t iProduct;
    uint8_t iSerialNumber;
    uint8_t bNumConfigurations;
} usb_device_desc;

typedef volatile struct {
    uint8_t bLength;
    uint8_t bDescriptorType;
    uint16_t wTotalLength;
    uint8_t bNumInterfaces;
    uint8_t bConfigurationValue;
    uint8_t iConfiguration;
    uint8_t bmAttributes;
    uint8_t bMaxPower;
} usb_config_desc;

typedef volatile struct {
    uint8_t bLength;
    uint8_t bDescriptorType;
    uint8_t bInterfaceNumber;
    uint8_t bAlternateSetting;
    uint8_t bNumEndpoints;
    uint8_t bInterfaceClass;
    uint8_t bInterfaceSubClass;
    uint8_t bInterfaceProtocol;
    uint8_t iInterface;
} usb_interface_desc;

// operational registers
#define EHCI_USBCMD_RUN (1 << 0) // 启动ehci
#define EHCI_USBCMD_RESET (1 << 1) // 重置ehci
#define EHCI_CONFIGFLAG (1 << 0) // 所有端口路由到ehci
#define EHCI_PORTSC_POWERON (1 << 12) // 端口电源
#define EHCI_PORTSC_ENABLE (1 << 2) // 端口启用
#define EHCI_PORTSC_RESET (1 << 8) // 端口重置
#define EHCI_PORTSC_CONNECT (1 << 0) // 端口连接状态


/* ---------- EHCI 寄存器 ---------- */
typedef volatile struct {
    uint8_t cap_len;
    uint8_t reserved;
    uint16_t version;
    uint32_t sparams;
    uint32_t cparams;
    uint64_t companion;
} ehci_cap_regs_t;

typedef volatile struct {
    uint32_t usbcmd;
    uint32_t usbsts;
    uint32_t usbintr;
    uint32_t frindex;
    uint32_t ctrldssegment;
    uint32_t periodiclistbase;
    uint32_t asynclistaddr;
    uint32_t _pad[9];
    uint32_t configflag;
    uint32_t portsc[15];
} ehci_regs_t;

/* ---------- 数据结构 ---------- */
typedef struct {
    uint32_t next;
    uint32_t alt;
    uint32_t token;
    uint32_t buf[5];
} qtd_t;

typedef struct {
    uint32_t horizontal;
    uint32_t static_ep;
    uint32_t ep_cap;
    uint32_t current_qtd_phy;
    struct {
		uint32_t		next_phy;
		uint32_t		alt_next_phy;
		uint32_t		token;
		uint32_t		buffer_phy[5];
		uint32_t		ext_buffer_phy[5];
	} overlay;
} qh_t;

int usb_init();
void usb_read(int sector, uint8_t *addr);

#endif
